home *** CD-ROM | disk | FTP | other *** search
- ; UCD.COM
- ;
- ; Uwe H. Steinfeld, 12/07/89
- ;
- ; Syntax: UCD [drive:][directory]
- ;
- ; Features: - fully replaces and enhances DOS' CD
- ; - is able to change drive and directory simultaneously
- ; - does not need a complete path to the target directory,
- ; searches recursively through the directory tree
- ;
- ; Limitation: - if two directories with the D:\
- ; same name in the tree exist │
- ; only the first will be found. ├─ STATS
- ; You have to give the name of │ ├─ EXCEL
- ; the parent directory to go │ │ └──── DATA
- ; to the desired one, e.g., │ └─ STATG
- ; to go to the second data │ └──── DATA
- ; directory on drive D: use
- ; UCD D:STATG\DATA
- ;
- ; Errorlevel: 0 success
- ; 1 directory not found
- ; 2 invalid drive
-
-
- include dos.inc ; MASM macros for better readable code
-
- directory equ 10000b ; directory attribute
-
- text segment
- assume cs:text, ds:text, es:text
-
- org 100h
-
- start: jmp ucd
-
- Copyright: db '(C) Uwe H. Steinfeld, 12/07/89'
- SaveDrive db 0, ':\'
- SaveDir db 64 dup (0),'$'
- search db 64 dup (0)
- root db '\', 0
- parent db '..', 0
- wild db '*.*', 0
- msg1 db 'Invalid directory', 0Dh, 0Ah, '$'
- msg2 db 'Invalid drive', 0Dh, 0Ah, '$'
-
-
- ucd: @GetDrv ; save current drive and path
- mov SaveDrive,al ; to go back if the search
- @GetDir SaveDir ; is unsuccessful
-
- mov si,81h ; start of command tail
- mov di,offset search ; ASCIIZ path storage
- Uc_1: lodsb
- cmp al,' ' ; skip leading blanks and
- jz Uc_1 ; tabs in the command tail
- cmp al,9
- jz Uc_1
- cmp al,0Dh ; end of command line ?
- jnz Uc_2
-
- add cs:SaveDrive,'A' ; no cmd line argument, just
- @DispStr SaveDrive ; display current drive
- @Exit 0 ; and path and terminate
-
- Uc_2: mov dl,al ; save first letter
- lodsb ; get next
- cmp al,':' ; drive specified ?
- jnz Uc_5
-
- ; set new drive
-
- and dl,0DFh ; adjust to uppercase
- sub dl,'A' ; drive A=0, B=1, ...
- mov ah,0Eh ; set new drive
- int 21h
- @GetDrv ; get drive
- cmp al,dl ; successful changed ?
- jz Uc_3
- @DispStr msg2 ; invalid drive specified
- @Exit 2 ; exit with errorlevel 2
-
- Uc_3: lodsb ; get next character
- call ChkEnd ; only new drive given ?
- jnz Uc_4
- @Exit 0 ; done
-
- Uc_4: mov dl,al ; save first letter
- lodsb
-
- Uc_5: xchg dl,al ; no drive given, so
- stosb ; store saved characters
- xchg al,dl
- call ChkEnd ; only 1 char on cmd line ?
- jnz Uc_7
-
- ; target directory only 1 character long, check for '\' and '.'
-
- cmp dl,'.' ; was it 'current' dir ?
- jnz Uc_6
- @Exit 0 ; then we're done
-
- Uc_6: cmp dl,'\' ; was it root dir ?
- jnz Uc_8
- @ChDir root ; then go to root dir
- @Exit 0 ; and quit
-
- ; more than 1 directory letter so check for '..'
-
- Uc_7: cmp al,'.' ; test first character
- jnz Uc_8
- cmp al,dl ; compare to second
- jnz Uc_8
- @ChDir parent ; change to parent directory
- @Exit 0 ; and exit
-
- ; read rest of command tail
-
- Uc_8: stosb
- lodsb ; get the rest of the cmd tail
- call ChkEnd ; don't care about what comes
- jnz Uc_8 ; after the first word
-
- ; search begins
-
- mov di,offset DTAInit ; ptr to start of DTA area
- @ChDir root ; start in the root directory
- call tree ; and call the subroutine
- mov dl,SaveDrive ; if we return here then the
- mov ah,0Eh ; directory was not found,
- int 21h ; so restore the starting
- @ChDir SaveDir ; drive/dir and stop with
- @DispStr msg1 ; error message
- @Exit 1
-
- ; tree search (recursively)
-
- tree: call setDTA ; set DTA for GetFirst/Next
- @GetFirst search,directory ; is 'target' subdirectory
- jc t1 ; of the current dir ?
- cmp byte ptr[di+15h],directory
- jnz t1
- @ChDir search ; then change to it and
- @Exit 0 ; exit with success code
-
- t1: @GetFirst wild,directory ; look for subdirectories...
- t2: jc t4
- cmp byte ptr[di+15h],directory
- jnz t3
- cmp byte ptr[di+1Eh],'.' ; ... but not '.' or '..'
- jz t3
- mov dx,di ; change directory to
- add dx,1Eh ; the one found
- mov ah,3Bh
- int 21h
- add di,43 ; increase dta ptr
- call tree ; and start over
- @ChDir parent ; come back if not found
- sub di,43 ; set dta ptr back
- call setDTA
- t3: @GetNext ; find next subdirectory
- jmp t2
- t4: ret
-
- setDTA: mov dx,di ; set new disk transfer area
- mov ah,1Ah
- int 21h
- ret
-
- ChkEnd: cmp al,' ' ; get byte from command line
- jz ChkRet ; and check for end of
- cmp al,9 ; line condition
- jc ChkRet
- cmp al,0Dh
- ChkRet: ret
-
- DTAInit: ; start of first DTA
-
- text ends
- end start
-